<?php

namespace App\Library\Logic;

use App\Library\Requests\Invite\InviteOrderPageRequest;
use App\Library\Requests\SalesRecord\SalesRecordPageRequest;
use App\Models\SalesRecordModel;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

class SalesRecordLogic extends SalesRecordModel
{
    /**
     * invite
     * @param ShopOrderLogic $order
     */
    public static function addOrEditOfShopOrder(Model $order): Model
    {
        $where = [
            'type' => 'order',
            'objectType' => $order->getTable(),
            'objectId' => $order->order_id,
            'toUserId' => $order->sell_user_id,
            'fromUserId' => $order->buy_user_id,
        ];
        $self = SalesRecordLogic::findByWhere($where);
        $commission = ShopOrderGoodsLogic::sumByWhere('orderId', $order->order_id, 'commission');
        $amount = bcsub(bcsub($order->pay_price, $order->order_ensure_price, 2), $commission ?? 0, 2);
        if (is_null($self)) {
            return SalesRecordLogic::insertForModel(array_merge($where, [
                'createdAt' => now()->timestamp($order->order_pay_time),
                'updatedAt' => now()->timestamp($order->order_pay_time),
                'amount' => $amount,
            ]));
        } else return SalesRecordLogic::updateForModel(['amount' => $amount], $self);
    }

    /**
     * shopOrderInvite
     * @param ShopOrderLogic $order
     * @return void
     */
    public static function shopOrderInvite(Model $order): void
    {
        $totalCommission = 0;//总佣金
        foreach ($order->goods as $v) {
            if (!empty($v->info['specInfo']['commission']) && $v->info['specInfo']['commission'] > 0) {
                $v->commission = $v->info['specInfo']['commission'] * $v->quantity;
            } else if (!empty($v->info['specInfo']['commission_ratio']) && $v->info['specInfo']['commission_ratio'] > 0) {
                $v->commission = bcmul($v->price * $v->quantity, bcdiv($v->info['specInfo']['commission_ratio'], 100, 2), 2);
            }
            $totalCommission = (float)bcadd($totalCommission, $v->commission, 2);
            $v->save();
        }

        if ($totalCommission == 0) return;

        //获取购买人被邀请信息
        $inviteeInfo = InviteLogic::getInviteeInfo($order->buy_user_id);

        if (is_null($inviteeInfo)) {//购买人未被邀请
            if (is_null($order->invite_code)) return;
            //获取邀请人基础信息
            $inviterUser = ShopUserLogic::findByWhere('inviteCode', $order->invite_code);
            if (is_null($inviterUser)) return;
            //邀请人被邀请信息
            $inviterInfo = InviteLogic::getInviteeInfo($inviterUser->user_id);

            if (is_null($inviterInfo)) {//邀请人无上级
                InviteLogic::insertForModel([
                    'inviterId' => $inviterUser->user_id,
                    'inviteeId' => $order->buy_user_id,
                    'level' => is_null($inviterInfo) ? 0 : 1,
                ]);
                self::commonSalesRecordInvite($order, $inviterUser->user_id, $order->buy_user_id, $totalCommission);
            } else {//邀请人有上级
                $commission = bcdiv($totalCommission, 2, 2);
                InviteLogic::insertForModel([
                    'inviterId' => $inviterUser->user_id,
                    'inviteeId' => $order->buy_user_id,
                    'level' => is_null($inviterInfo) ? 0 : 1,
                ]);

                self::commonSalesRecordInvite($order, $inviterUser->user_id, $order->buy_user_id, $commission);
                self::commonSalesRecordInvite($order, $inviterInfo->inviter_id, $inviterInfo->invitee_id, $commission);
            }
        } else {//购买人已被邀请
            $upperInviterInfo = InviteLogic::findByWhere(['inviteeId' => $inviteeInfo->inviter_id]);//购买人已存在的绑定关系是否存在上级绑定关系

            if (is_null($upperInviterInfo)) {
                self::commonSalesRecordInvite($order, $inviteeInfo->inviter_id, $inviteeInfo->invitee_id, $totalCommission);
            } else {
                $commission = bcdiv($totalCommission, 2, 2);
                self::commonSalesRecordInvite($order, $inviteeInfo->inviter_id, $inviteeInfo->invitee_id, $commission);
                self::commonSalesRecordInvite($order, $upperInviterInfo->inviter_id, $upperInviterInfo->invitee_id, $commission);
            }
        }
    }

    public static function fromUserOrderId(InviteOrderPageRequest $request): array
    {
        return self::query()->where([
            'type' => 'invite',
            'object_type' => 'shop_order',
            'from_user_id' => $request->user_id
        ])->distinct()->pluck('object_id')->toArray();
    }

    public static function toUserOrderId(): array
    {
        return self::query()->where([
            'type' => 'invite',
            'object_type' => 'shop_order',
            'to_user_id' => USERID
        ])->distinct()->pluck('object_id')->toArray();
    }

    /**
     * 邀请佣金销售记录
     * @param $order
     * @param $toUserId
     * @param $fromUserId
     * @param $commission
     * @return void
     */
    private static function commonSalesRecordInvite($order, $toUserId, $fromUserId, $commission): void
    {
        $where = [
            'type' => 'invite',
            'objectType' => $order->getTable(),
            'objectId' => $order->order_id,
            'toUserId' => $toUserId,
            'fromUserId' => $fromUserId,
        ];
        if (self::existsByWhere($where)) return;
        self::insertForModel(array_merge($where, [
            'amount' => $commission,
        ]));
    }

    public static function inviteRecode(): Model|Builder|null
    {
        return self::query()
            ->where([
                'to_user_id' => USERID,
                'type' => 'invite'
            ])
            ->select(DB::raw('
                count(if(sales_record.status, true, null)) as order_num,
                cast(sum(if(sales_record.status = 1, amount, 0)) as double) as credited_amount,
                cast(sum(if(sales_record.status = 0, amount, 0)) as double) as incoming_amount
            '))->first();
    }

    public static function inviteOrderPage(InviteOrderPageRequest $request): array
    {
        $builder = self::query()
            ->leftJoin('shop_order', 'shop_order.order_id', '=', 'sales_record.object_id')
            ->leftJoin('shop_order_ext', 'shop_order.order_id', 'shop_order_ext.order_id')
            ->leftJoin('shop_user as user', 'user.user_id', 'shop_order.buy_user_id')
            ->leftJoin('shop_user as seller', 'seller.user_id', 'shop_order.sell_user_id')
            ->with(['orderExt'])
            ->with(['goods' => function ($query) use ($request) {
                $query->select();
                if (!is_null($request->keyword)) {
                    $query->orWhere('title', 'like', '%' . $request->keyword . '%')
                        ->orWhere(function ($query) use ($request) {
                            $query->whereJsonContains('info->specInfo->ps_name', $request->keyword);
                        });
                }
            }])
            ->where([
                'to_user_id' => 8,
                'type' => 'invite',
                'object_type' => 'shop_order',
            ]);

        if (!is_null($request->mobile)) {
            $builder->where(function ($query) use ($request) {
                $query->where('user.user_mobile', 'like', '%' . $request->mobile . '%')
                    ->orWhere('seller.user_mobile', 'like', '%' . $request->mobile . '%');
            });
        }

        if (!is_null($request->status) || $request->status !== 0) {
            if ($request->status === 1) $builder->where(['shop_order_ext.status' => 2, 'status_deliver' => 0]);//待发货
            else if ($request->status === 2) $builder->where(['shop_order_ext.status_confirm' => 0, 'status_deliver' => 1]);//待收货
            else if ($request->status === 3) $builder->where('shop_order_ext.status', 4);//已完成
            else if ($request->status === 4) $builder->where('shop_order_ext.status_after_sale', 1);//售后中
            else if ($request->status === 5) $builder->where('shop_order_ext.status_settlement', 1);//结算完成
        }

        return paginate($builder->paginate($request->limit, [
            'shop_order.order_id',
            'shop_order.serial_number',
            'shop_order.order_total_real_price',
            'shop_order.pay_price',
            'shop_order.add_at',
            'sales_record.amount',
            'shop_order.order_note'
        ]));
    }

    public function paging(SalesRecordPageRequest $request)
    {
        $builder = self::query()->where('to_user_id', USERID);
        switch ($request->type) {
            case 1:
                $builder->where('type', 'order');
                break;
            case 2:
                $builder->where('type', 'auction');
                break;
            case 3:
                $builder->where('type', 'invite');
                break;
            case 4:
                $builder->where('type', 'box');
                break;
            case 5:
                $builder->where('type', 'ticket');
                break;
        }
        if (is_null($request->listType) || !$request->listType) $builder->where('status', 0);
        return paginate($builder->orderByDesc('created_at')->paginate($request->limit));
    }

    public function creditedAmount(): Model|Builder|null
    {
        return self::query()
            ->where([
                'to_user_id' => USERID
            ])
            ->select(DB::raw('
                cast(sum(if(sales_record.status = 0, amount, 0)) as double) as credited_amount
            '))->first();
    }
}
